﻿using System;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace BrightSword.Crucible
{
    public static class ExceptionHelper
    {
        public static TException ExpectException<TException>(
            this Action action,
            string expectedExceptionMessage = null) where TException : Exception
        {
            try
            {
                action();

                Assert.Fail("An exception of type '{0}' was expected but not thrown",
                            typeof (TException).Name);
            }
            catch (Exception exception)
            {
                var local = exception as TException;

                if (local == null)
                {
                    Assert.Fail("An exception of type '{0}' was expected, but an exception of type '{1}', with message '{2}' was thrown instead.",
                                new object[]
                                {
                                    typeof (TException).Name, exception.GetType()
                                                                       .Name,
                                    exception.Message
                                });
                }

                if (string.IsNullOrWhiteSpace(expectedExceptionMessage))
                {
                    return local;
                }

                if (local.Message.Equals(expectedExceptionMessage,
                                         StringComparison.InvariantCultureIgnoreCase))
                {
                    return local;
                }

                Assert.Fail("An exception of type '{0}' with message '{1}' was expected. The exception was thrown but the exception message was '{2}'.",
                            new object[]
                            {
                                typeof (TException).Name, expectedExceptionMessage, local.Message
                            });

            }            
            
            return null;
        }
    }
}